home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / Documentation / d e v e l o p / Develop Issue 23 article / Geometry Sample / QD3D src / Geometries.c next >
Encoding:
C/C++ Source or Header  |  1996-05-21  |  34.3 KB  |  1,375 lines  |  [TEXT/MPCC]

  1. /******************************************************************************
  2.  **                                                                             **
  3.  **     Module:        Geometrys.c                                                  **
  4.  **                                                                          **
  5.  **                                                                          **
  6.  **     Purpose:                                                              **
  7.  **                                                                          **
  8.  **                                                                          **
  9.  **                                                                          **
  10.  **     Copyright (C) 1992-1995 Apple Computer, Inc.  All rights reserved.     **
  11.  **                                                                          **
  12.  **                                                                          **
  13.  **     Change Log:                                                             **
  14.  **                                                                          **
  15.  **                                                                          **
  16.  *****************************************************************************/
  17. #include <stdlib.h>
  18.  
  19. #include "QD3D.h"
  20. #include "QD3DGeometry.h"
  21. #include "QD3DTransform.h"
  22. #include "QD3DGroup.h"
  23. #include "QD3DSet.h"
  24. #include "QD3DShader.h"
  25. #include "QD3DDrawContext.h"
  26.  
  27. #include "AttributeSet_Lib.h"
  28. #include "QD3DStyle.h"
  29.  
  30. #include "QD3DMath.h"
  31. #include "Geometries.h"
  32.  
  33. TextureRec    gTextureEntries[8];
  34.  
  35.  
  36. /******************************************************************************
  37.  **                                                                             **
  38.  **                                    Defines                                     **
  39.  **                                                                             **
  40.  *****************************************************************************/
  41.  
  42.  
  43. #define UVERTICES    11            /* For Scene object */
  44. #define VVERTICES    11
  45. #define FULLMESH    0            /* Set this to 1 to show a bug in mesh attrib. inheritance (??) */
  46.  
  47. /******************************************************************************
  48.  **                                                                             **
  49.  **                            Local Declarations                                 **
  50.  **                                                                             **
  51.  *****************************************************************************/
  52.  
  53. static TQ3GroupObject    BuildBox(
  54.     void);
  55.         
  56. static TQ3GroupObject    BuildGeneralPolygon(
  57.     void);
  58.     
  59. static TQ3GroupObject    BuildLine(
  60.     void);
  61.     
  62. static TQ3GroupObject    BuildMarker(
  63.     void);
  64.     
  65. static TQ3GroupObject    BuildNURBCurve(
  66.     void);
  67.     
  68. static TQ3GroupObject    BuildNURBPatch(
  69.     void);
  70.     
  71. static TQ3GroupObject    BuildPoint(
  72.     void);
  73.     
  74. static TQ3GroupObject    BuildPolygon(
  75.     void);
  76.     
  77. static TQ3GroupObject    BuildPolyLine(
  78.     void);
  79.     
  80. static TQ3GroupObject    BuildMesh(
  81.     void);
  82.     
  83. static TQ3GroupObject    BuildCursor(
  84.     void);
  85.     
  86. static TQ3GroupObject    BuildTriangle(
  87.     void);
  88.     
  89. static TQ3GroupObject    BuildTriGrid(
  90.     void);
  91.     
  92. static TQ3GroupObject BuildScene(
  93.     void);
  94.  
  95. /******************************************************************************
  96.  **                                                                             **
  97.  **                            API Routines                                     **
  98.  **                                                                             **
  99.  *****************************************************************************/
  100.  
  101. /*===========================================================================*\
  102.  *
  103.  *    Routine:    BuildGeometry()
  104.  *
  105.  *    Comments:    
  106.  *
  107. \*===========================================================================*/
  108.     
  109. TQ3GroupObject BuildGeometry(short type)
  110. {
  111.     TQ3GroupObject    model = NULL;
  112.  
  113.     switch (type) {
  114.         case iMarker:
  115.             model = BuildMarker();
  116.             break;
  117.         case iPoint:
  118.             model = BuildPoint();
  119.             break;
  120.         case iLine:
  121.             model = BuildLine();
  122.             break;
  123.         case iPolyline:
  124.             model = BuildPolyLine();
  125.             break;
  126.         case iTriangle:
  127.             model = BuildTriangle();
  128.             break;
  129.         case iPolygon:
  130.             model = BuildPolygon();
  131.             break;
  132.         case iGeneralPolygon:
  133.             model = BuildGeneralPolygon();
  134.             break;
  135.         case iTrigrid:
  136.             model = BuildTriGrid();
  137.             break;
  138.         case iBox:
  139.             model = BuildBox();
  140.             break;
  141.         case iMesh:
  142.             model = BuildMesh();
  143.             break;
  144.         case iNurbCurve:
  145.             model = BuildNURBCurve();
  146.             break;
  147.         case iNurbPatch:
  148.             model = BuildNURBPatch();
  149.             break;
  150.     }
  151.     
  152.     return (model);
  153.     
  154. }
  155.  
  156. /******************************************************************************
  157.  **                                                                             **
  158.  **                            Local Routines                                     **
  159.  **                                                                             **
  160.  *****************************************************************************/
  161.  
  162. /*===========================================================================*\
  163.  *
  164.  *    Routine:    BuildMarker()
  165.  *
  166.  *
  167. \*===========================================================================*/
  168.  
  169. static TQ3GroupObject BuildMarker(
  170.     void)
  171. {
  172.     TQ3GroupObject        model;
  173.     TQ3MarkerData        markerData;
  174.     TQ3GeometryObject    marker;
  175.     TQ3ColorRGB            markerColor;
  176.  
  177.  
  178.     TQ3Bitmap            *bitmapPtr = &markerData.bitmap;
  179.     unsigned char        imageData[] = {
  180.                             0x7E, 0x3C, 0x3C, 0x66, 0x7E, 0x7C, 0x18,
  181.                             0x60, 0x60, 0x66, 0x66, 0x60, 0x66, 0x18,
  182.                             0x7C, 0x3C, 0x60, 0x7E, 0x7C, 0x66, 0x18,
  183.                             0x60, 0x06, 0x60, 0x66, 0x60, 0x7C, 0x18,
  184.                             0x60, 0x06, 0x66, 0x66, 0x60, 0x66, 0x00,
  185.                             0x7E, 0x3C, 0x3C, 0x66, 0x7E, 0x66, 0x18
  186.                         };
  187.     
  188.     Q3Point3D_Set(&markerData.location, 0, 1, 1);
  189.     markerData.xOffset    = -28;
  190.     markerData.yOffset    = -3;
  191.     markerData.markerAttributeSet = Q3AttributeSet_New();
  192.     
  193.     markerColor.r = 0.8;
  194.     markerColor.g = 0.2;
  195.     markerColor.b = 0.6;
  196.     AttributeSet_AddDiffuseColor(markerData.markerAttributeSet, &markerColor);
  197.  
  198.  
  199.     bitmapPtr->image    = imageData;
  200.     bitmapPtr->width    = 56;
  201.     bitmapPtr->height    = 6;
  202.     bitmapPtr->rowBytes    = 7;
  203.     bitmapPtr->bitOrder    = kQ3EndianBig;
  204.     
  205.     marker = Q3Marker_New(&markerData);
  206.     model = Q3OrderedDisplayGroup_New();
  207.     
  208.     if (marker != NULL) {
  209.         Q3Group_AddObject(model, marker);    
  210.     
  211.         Q3Object_Dispose(marker);
  212.     }
  213.     
  214.     Q3Object_Dispose(markerData.markerAttributeSet);
  215.  
  216.     return (model);    
  217. }
  218.  
  219.  
  220. /*===========================================================================*\
  221.  *
  222.  *    Routine:    BuildPoint()
  223.  *
  224.  *    Comments:    
  225.  *
  226. \*===========================================================================*/
  227.  
  228. static TQ3GroupObject BuildPoint(
  229.     void)
  230. {
  231.     TQ3GroupObject        model;
  232.     TQ3PointData            pointData;
  233.     TQ3GeometryObject    pointThang;
  234.     TQ3ColorRGB            pointColor;
  235.     
  236.     model = Q3OrderedDisplayGroup_New();
  237.  
  238.     Q3Point3D_Set(&pointData.point, 1, 1, 1);
  239.     pointData.pointAttributeSet = NULL;
  240.     
  241.     pointData.pointAttributeSet = Q3AttributeSet_New();
  242.     
  243.     
  244.     Q3ColorRGB_Set(&pointColor, 0.0, 1.0, 0.0);
  245.     AttributeSet_AddDiffuseColor(pointData.pointAttributeSet, &pointColor);
  246.  
  247.     pointThang = Q3Point_New(&pointData);
  248.     if (pointThang != NULL) {
  249.         Q3Group_AddObject(model, pointThang);
  250.         Q3Object_Dispose(pointThang);
  251.     }        
  252.     Q3Object_Dispose(pointData.pointAttributeSet);
  253.     
  254.     return (model);    
  255.  
  256. }
  257.  
  258. /*===========================================================================*\
  259.  *
  260.  *    Routine:    BuildLine()
  261.  *
  262.  *    Comments:    
  263.  *
  264. \*===========================================================================*/
  265.     
  266. static TQ3GroupObject BuildLine(
  267.     void)
  268. {
  269.     TQ3ColorRGB            lineColor;
  270.     TQ3GroupObject        model;
  271.     TQ3LineData            lineData;
  272.     TQ3GeometryObject    lineThang;
  273.  
  274.     lineData.lineAttributeSet = Q3AttributeSet_New();
  275.     lineColor.r = 0.3;
  276.     lineColor.g = 0.9;
  277.     lineColor.b = 0.9;
  278.     AttributeSet_AddDiffuseColor(lineData.lineAttributeSet, &lineColor);
  279.     
  280. #define DO_TEST_LINE 1
  281. #if DO_TEST_LINE
  282.     lineData.vertices[0].point.x = -1.0;
  283.     lineData.vertices[0].point.y =  0.0;
  284.     lineData.vertices[0].point.z =  0.0;
  285.     lineData.vertices[0].attributeSet = NULL;
  286.     
  287.     lineData.vertices[1].point.x =  1.0;
  288.     lineData.vertices[1].point.y =  0.0;;
  289.     lineData.vertices[1].point.z =  0.0;;
  290.     lineData.vertices[1].attributeSet = NULL;
  291. #else
  292.     lineData.vertices[0].point.x = -1.0;
  293.     lineData.vertices[0].point.y = -0.5;
  294.     lineData.vertices[0].point.z = -0.25;
  295.     lineData.vertices[0].attributeSet = NULL;
  296.     
  297.     lineData.vertices[1].point.x =  2.0;
  298.     lineData.vertices[1].point.y =  1.5;
  299.     lineData.vertices[1].point.z =  2.25;
  300.     lineData.vertices[1].attributeSet = NULL;
  301. #endif  /*  DO_TEST_LINE  */
  302. #undef DO_TEST_LINE
  303.  
  304.     lineThang = Q3Line_New(&lineData);
  305.     
  306.     model = Q3OrderedDisplayGroup_New();
  307.     
  308.     Q3Group_AddObject(model, lineThang);    
  309.  
  310.     Q3Object_Dispose(lineData.lineAttributeSet);
  311.     Q3Object_Dispose(lineThang);
  312.     
  313.     return (model);    
  314. }
  315.  
  316. /*===========================================================================*\
  317.  *
  318.  *    Routine:    BuildPolyLine()
  319.  *
  320.  *    Comments:    
  321.  *
  322. \*===========================================================================*/
  323.     
  324. static TQ3GroupObject BuildPolyLine(
  325.     void)
  326. {
  327.     TQ3ColorRGB            polyLineColor;
  328.  
  329.     TQ3GroupObject        model;
  330.     TQ3PolyLineData        polyLineData;
  331.     TQ3GeometryObject    polyLineThang;
  332.     static TQ3Vertex3D    points[4] = {
  333.                             {{ -1.0, -0.5, -0.25 }, NULL },
  334.                             {{ -0.5,  1.5,  0.45 }, NULL },
  335.                             {{  0.0,  0.0,  0.0  }, NULL },
  336.                             {{  1.5,  1.5,  1.0  }, NULL }
  337.                         };
  338.  
  339.     
  340.     polyLineData.numVertices             = 4;
  341.     polyLineData.vertices                 = points;
  342.     polyLineData.segmentAttributeSet     = malloc(3 * sizeof(TQ3AttributeSet));
  343.     
  344.     {
  345.         unsigned long     i;
  346.         TQ3ColorRGB        segmentColor;
  347.         
  348.         segmentColor.r = 1.0;
  349.         segmentColor.g = 0.0;
  350.         segmentColor.b = 0.2;
  351.         
  352.         for (i = 0; i < polyLineData.numVertices - 1; i++) {
  353.             polyLineData.segmentAttributeSet[i] = NULL;
  354.         }
  355.         
  356.         polyLineData.segmentAttributeSet[1] = Q3AttributeSet_New();
  357.         
  358.         AttributeSet_AddDiffuseColor(polyLineData.segmentAttributeSet[1], 
  359.                                        &segmentColor);
  360.  
  361.     }            
  362.     
  363.     polyLineData.polyLineAttributeSet = NULL;
  364.  
  365.  
  366.     polyLineData.polyLineAttributeSet = Q3AttributeSet_New();
  367.     polyLineColor.r = 0.4;
  368.     polyLineColor.g = 0.2;
  369.     polyLineColor.b = 0.9;
  370.     AttributeSet_AddDiffuseColor(polyLineData.polyLineAttributeSet, &polyLineColor);
  371.  
  372.     polyLineThang = Q3PolyLine_New(&polyLineData);
  373.     
  374.     model = Q3OrderedDisplayGroup_New();
  375.     Q3Group_AddObject(model, polyLineThang);    
  376.  
  377.  
  378.     Q3Object_Dispose(polyLineData.polyLineAttributeSet);
  379.     Q3Object_Dispose(polyLineData.segmentAttributeSet[1]);
  380.     free(polyLineData.segmentAttributeSet);
  381.     Q3Object_Dispose(polyLineThang);
  382.     
  383.     return (model);
  384. }
  385.  
  386.  
  387. /*===========================================================================*\
  388.  *
  389.  *    Routine:    BuildTriangle()
  390.  *
  391.  *    Comments:    This geometry is really interesting, it's worth a bit of study
  392.  *                since we add an overall beige colour, and then add a color to 
  393.  *                each of the vertices.  So if you view it with flat interpolation
  394.  *                it looks like that beige/brown colour, but if you view with per
  395.  *                vertex interpolation you'll see the cool colors we attach to each
  396.  *                vertex.  Check it out!!
  397.  *
  398. \*===========================================================================*/
  399.  
  400. static TQ3GroupObject BuildTriangle(
  401.     void)
  402. {
  403.     TQ3ColorRGB            triangleColor;
  404.  
  405.     TQ3GroupObject        model;
  406.     TQ3TriangleData        triangleData;
  407.     TQ3GeometryObject    triangleThang;
  408.     static TQ3Vertex3D    vertices[3] = {
  409.                             { { -1.0, -0.5, -0.25 }, NULL },
  410.                             { {  0.0,  0.0,  0.0  }, NULL },
  411.                             { { -0.5,  1.5,  0.45 }, NULL },
  412.                         };
  413.  
  414.     triangleData.vertices[0] = vertices[0];
  415.     triangleData.vertices[1] = vertices[1];
  416.     triangleData.vertices[2] = vertices[2];
  417.     
  418.     triangleData.triangleAttributeSet = Q3AttributeSet_New();
  419.     triangleColor.r = 0.8;
  420.     triangleColor.g = 0.5;
  421.     triangleColor.b = 0.2;
  422.     AttributeSet_AddDiffuseColor(triangleData.triangleAttributeSet, &triangleColor);
  423.  
  424.     triangleData.vertices[0].attributeSet = Q3AttributeSet_New();
  425.     triangleData.vertices[1].attributeSet = Q3AttributeSet_New();
  426.     triangleData.vertices[2].attributeSet = Q3AttributeSet_New();
  427.     triangleColor.r = 1.0;
  428.     triangleColor.g = 0.0;
  429.     triangleColor.b = 0.0;
  430.     AttributeSet_AddDiffuseColor(triangleData.vertices[0].attributeSet, &triangleColor);
  431.     triangleColor.r = 0.0;
  432.     triangleColor.g = 1.0;
  433.     triangleColor.b = 0.0;
  434.     AttributeSet_AddDiffuseColor(triangleData.vertices[1].attributeSet, &triangleColor);
  435.     triangleColor.r = 0.0;
  436.     triangleColor.g = 0.0;
  437.     triangleColor.b = 1.0;
  438.     AttributeSet_AddDiffuseColor(triangleData.vertices[2].attributeSet, &triangleColor);
  439.  
  440.     triangleThang = Q3Triangle_New(&triangleData);
  441.     
  442.     model = Q3OrderedDisplayGroup_New();
  443.  
  444.     if (triangleThang != NULL) {
  445.         Q3Group_AddObject(model, triangleThang);    
  446.     
  447.         Q3Object_Dispose(triangleThang);
  448.     }
  449.     
  450.     Q3Object_Dispose(triangleData.vertices[0].attributeSet);
  451.     Q3Object_Dispose(triangleData.vertices[1].attributeSet);
  452.     Q3Object_Dispose(triangleData.vertices[2].attributeSet);
  453.     Q3Object_Dispose(triangleData.triangleAttributeSet);
  454.  
  455.     return (model);    
  456. }
  457.  
  458. /*===========================================================================*\
  459.  *
  460.  *    Routine:    BuildPolygon()
  461.  *
  462.  *    Comments:    
  463.  *
  464. \*===========================================================================*/
  465.  
  466. static TQ3GroupObject BuildPolygon(
  467.     void)
  468. {
  469.     TQ3GroupObject        model;
  470.     TQ3PolygonData        polygonData;
  471.     TQ3GeometryObject    polygonThang;
  472.     static TQ3Vertex3D    vertices[4] = {
  473.                             { { -2.0,  1.0,  0.0 }, NULL },
  474.                             { { -1.0, -1.0,  0.0 }, NULL },
  475.                             { {  1.0, -1.0,  0.0 }, NULL },
  476.                             { {  1.0,  1.0,  0.0 }, NULL },
  477.                         };
  478.     
  479.     polygonData.numVertices         = 4;
  480.     polygonData.vertices             = vertices;
  481.     polygonData.polygonAttributeSet = NULL;
  482.     
  483.     polygonThang = Q3Polygon_New(&polygonData);
  484.     
  485.     model = Q3OrderedDisplayGroup_New();
  486.     
  487.     Q3Group_AddObject(model, polygonThang);    
  488.     
  489.     Q3Object_Dispose(polygonThang);
  490.     
  491.     return (model);    
  492.  
  493. }
  494.  
  495.  
  496. /*===========================================================================*\
  497.  *
  498.  *    Routine:    BuildGeneralPolygon()
  499.  *
  500.  *    Comments:    
  501.  *
  502. \*===========================================================================*/
  503.  
  504. static TQ3GroupObject BuildGeneralPolygon(
  505.     void)
  506. {
  507.     TQ3GroupObject                    model;
  508.     TQ3GeneralPolygonData            genPolyData;
  509.     TQ3GeneralPolygonContourData    contours[2];
  510.     TQ3GeometryObject                polygonThang;
  511. #if 0
  512.     static TQ3Vertex3D        vertices1[4] = {
  513.                                 { { -1.0, -0.5, -0.25 }, NULL },
  514.                                 { {  0.0,  0.0, -0.25 }, NULL },
  515.                                 { { -0.5,  1.5, -0.25 }, NULL },
  516.                                 { { -1.0,  2.5, -0.25 }, NULL }
  517.                             };
  518.                         
  519.     static TQ3Vertex3D        vertices2[4] = {
  520.                                 { { -0.7, -0.4, -0.25 }, NULL },
  521.                                 { {  0.2,  0.2, -0.25 }, NULL },
  522.                                 { { -0.3,  1.2, -0.25 }, NULL },
  523.                                 { { -1.0,  2.5, -0.25 }, NULL }
  524.                             };
  525. #else
  526.     static TQ3Vertex3D        vertices1[3] = {
  527.                                 { { -1.0,  0.0, 0.0 }, NULL },
  528.                                 { {  1.0,  0.0, 0.0 }, NULL },
  529.                                 { {  0.0,  1.7, 0.0 }, NULL }
  530.                             };
  531.                         
  532.     static TQ3Vertex3D        vertices2[3] = {
  533.                                 { { -1.0,  0.4, 0.0 }, NULL },
  534.                                 { {  1.0,  0.4, 0.0 }, NULL },
  535.                                 { {  0.0,  2.1, 0.0 }, NULL }
  536.                             };
  537. #endif
  538.     TQ3ColorRGB                color;
  539.  
  540.     
  541.     contours[0].numVertices         = 3;
  542.     contours[0].vertices             = vertices1;
  543.     
  544.     contours[1].numVertices         = 3;
  545.     contours[1].vertices             = vertices2;
  546.  
  547.     genPolyData.numContours                 = 2;
  548.     genPolyData.contours                     = contours;
  549.     genPolyData.shapeHint                    = kQ3GeneralPolygonShapeHintComplex;
  550.     genPolyData.generalPolygonAttributeSet     = Q3AttributeSet_New();
  551.     
  552.     color.r = 0.0; color.g = 1.0; color.b = 1.0;
  553.     AttributeSet_AddDiffuseColor(genPolyData.generalPolygonAttributeSet, &color);
  554.  
  555.     vertices1[1].attributeSet = Q3AttributeSet_New();
  556.     vertices1[2].attributeSet = Q3AttributeSet_New();
  557.     
  558.     color.r = 0.0; color.g = 0.0; color.b = 1.0;
  559.     AttributeSet_AddDiffuseColor(vertices1[1].attributeSet, &color);
  560.     
  561.     color.r = 0.0; color.g = 1.0; color.b = 1.0;
  562.     AttributeSet_AddDiffuseColor(vertices1[2].attributeSet, &color);
  563.     
  564.     vertices2[0].attributeSet = Q3AttributeSet_New();
  565.     vertices2[2].attributeSet = Q3AttributeSet_New();
  566.     
  567.     color.r = 1.0; color.g = 0.0; color.b = 1.0;
  568.     AttributeSet_AddDiffuseColor(vertices2[0].attributeSet, &color);
  569.     
  570.     color.r = 1.0; color.g = 1.0; color.b = 0.0;
  571.     AttributeSet_AddDiffuseColor(vertices2[2].attributeSet, &color);
  572.     
  573.     polygonThang = Q3GeneralPolygon_New(&genPolyData);
  574.     
  575.     model = Q3OrderedDisplayGroup_New();
  576.     
  577.     if (polygonThang != NULL) {
  578.         Q3Group_AddObject(model, polygonThang);    
  579.         Q3Object_Dispose(polygonThang);
  580.     }
  581.  
  582.     Q3Object_Dispose(vertices1[1].attributeSet);
  583.     Q3Object_Dispose(vertices1[2].attributeSet);
  584.     Q3Object_Dispose(vertices2[0].attributeSet);
  585.     Q3Object_Dispose(vertices2[2].attributeSet);
  586.     Q3Object_Dispose(genPolyData.generalPolygonAttributeSet);
  587.     
  588.     return (model);    
  589. }
  590.  
  591.  
  592. /*===========================================================================*\
  593.  *
  594.  *    Routine:    BuildTriGrid()
  595.  *
  596.  *    Comments:    
  597.  *
  598. \*===========================================================================*/
  599.     
  600. static TQ3GroupObject BuildTriGrid(
  601.     void)
  602. {
  603.     TQ3ColorRGB            triGridColor;
  604.  
  605.     TQ3GroupObject        model;
  606.     TQ3TriGridData        triGridData;
  607.     TQ3GeometryObject    triGridThang;
  608.     unsigned long        numFacets, i;
  609.  
  610.     static TQ3Vertex3D    vertices[12] = {
  611.                             { { -1.0,  -1.0,  0.0 }, NULL },
  612.                             { { -0.5, -1.0,  0.0 }, NULL },
  613.                             { {  0.0,  -1.0,  0.1 }, NULL },
  614.                             { {  0.2, -1.3,  0.2 }, NULL },
  615.     
  616.                             { { -1.0,  0.0,  0.0 }, NULL },
  617.                             { { -0.5, 0.0,  0.3 }, NULL },
  618.                             { {  0.0,  0.2,  0.0 }, NULL },
  619.                             { {  0.5, 0.0,  0.0 }, NULL },
  620.                         
  621.                             { { -1.0,  1.0,  1.0 }, NULL },
  622.                             { { -0.5, 1.0,  0.0 }, NULL },
  623.                             { {  0.0,  1.0,  0.0 }, NULL },
  624.                             { {  0.7, 1.0,  0.5 }, NULL },
  625.                         };
  626.     
  627.     triGridData.numRows = 3;
  628.     triGridData.numColumns = 4;
  629.     triGridData.vertices  = (TQ3Vertex3D *)malloc(12 * sizeof(TQ3Vertex3D));
  630.     triGridData.vertices[0] = vertices[0];
  631.     triGridData.vertices[1] = vertices[1];
  632.     triGridData.vertices[2] = vertices[2];
  633.     triGridData.vertices[3] = vertices[3];
  634.     triGridData.vertices[4] = vertices[4];
  635.     triGridData.vertices[5] = vertices[5];
  636.     triGridData.vertices[6] = vertices[6];
  637.     triGridData.vertices[7] = vertices[7];
  638.     triGridData.vertices[8] = vertices[8];
  639.     triGridData.vertices[9] = vertices[9];
  640.     triGridData.vertices[10] = vertices[10];
  641.     triGridData.vertices[11] = vertices[11];
  642.  
  643.     triGridData.facetAttributeSet = NULL;
  644.     
  645.     triGridData.triGridAttributeSet = Q3AttributeSet_New();
  646.     
  647.     triGridColor.r = 0.8;
  648.     triGridColor.g = 0.7;
  649.     triGridColor.b = 0.3;
  650.  
  651.     AttributeSet_AddDiffuseColor(triGridData.triGridAttributeSet, &triGridColor);
  652.     
  653.     numFacets = (triGridData.numRows - 1) *  (triGridData.numColumns - 1) *  2 ;
  654.     triGridData.facetAttributeSet = malloc(numFacets * sizeof(TQ3AttributeSet));
  655.     
  656.     for (i = 0; i < numFacets; i++) {
  657.         triGridData.facetAttributeSet[i] = NULL;
  658.     }
  659.     
  660.     triGridColor.r = 1.0;
  661.     triGridColor.g = 0.0;
  662.     triGridColor.b = 0.5;
  663.                                               
  664.     triGridData.facetAttributeSet[5] = Q3AttributeSet_New();                        
  665.     AttributeSet_AddDiffuseColor(triGridData.facetAttributeSet[5], &triGridColor);
  666.     
  667.     triGridThang = Q3TriGrid_New(&triGridData);
  668.     
  669.     model = Q3OrderedDisplayGroup_New();
  670.     
  671.     Q3Group_AddObject(model, triGridThang);    
  672.     
  673.     Q3Object_Dispose(triGridThang);
  674.     Q3Object_Dispose(triGridData.triGridAttributeSet);
  675.     Q3Object_Dispose(triGridData.facetAttributeSet[5]);
  676.     free(triGridData.facetAttributeSet);
  677.  
  678.     return (model);    
  679. }
  680.  
  681.  
  682.  
  683. /*===========================================================================*\
  684.  *
  685.  *    Routine:    BuildBox()
  686.  *
  687.  *    Comments:    
  688.  *
  689. \*===========================================================================*/
  690.     
  691. static TQ3GroupObject BuildBox(
  692.     void)
  693. {
  694.     TQ3ColorRGB            faceColor;
  695.  
  696.     TQ3GroupObject        model;
  697.     TQ3BoxData            boxData;
  698.     TQ3GeometryObject    boxThang;
  699.     
  700.     Q3Point3D_Set(&boxData.origin, 0, 0, 0);
  701.     Q3Vector3D_Set(&boxData.orientation, 0, 1, 0);
  702.     Q3Vector3D_Set(&boxData.majorAxis, 0, 0, 1);    
  703.     Q3Vector3D_Set(&boxData.minorAxis, 1, 0, 0);    
  704.     boxData.boxAttributeSet = Q3AttributeSet_New();
  705.     faceColor.r = 0.9;
  706.     faceColor.g = 0.9;
  707.     faceColor.b = 0.2;
  708.     AttributeSet_AddDiffuseColor(boxData.boxAttributeSet, &faceColor);
  709.  
  710.     boxData.faceAttributeSet = NULL;
  711.     
  712.     
  713.     boxData.faceAttributeSet = malloc(6 * sizeof(TQ3AttributeSet));
  714.     
  715.     {
  716.         register unsigned long i;
  717.         
  718.         for (i = 0; i < 6; i++) {
  719.             boxData.faceAttributeSet[i] = NULL;
  720.         }
  721.     }
  722.     
  723.     if(gTextureEntries[0].shader != NULL)
  724.     {
  725.         
  726.         boxData.faceAttributeSet[0] = Q3AttributeSet_New();
  727.         
  728.         AttributeSet_AddSurfaceShader(
  729.             boxData.faceAttributeSet[0],
  730.             (TQ3SurfaceShaderObject *)&gTextureEntries[0].shader);
  731.     }
  732.     
  733.     if(gTextureEntries[1].shader != NULL)
  734.     {
  735.         
  736.         boxData.faceAttributeSet[1] = Q3AttributeSet_New();
  737.         
  738.         AttributeSet_AddSurfaceShader(
  739.             boxData.faceAttributeSet[1],
  740.             (TQ3SurfaceShaderObject *)&gTextureEntries[1].shader);
  741.         
  742.         Q3Object_Dispose(gTextureEntries[1].shader);
  743.     }
  744.     
  745.     boxData.faceAttributeSet[2] = Q3AttributeSet_New();
  746.     if(gTextureEntries[2].shader != NULL)
  747.     {
  748.         AttributeSet_AddSurfaceShader(
  749.             boxData.faceAttributeSet[2],
  750.             (TQ3SurfaceShaderObject *)&gTextureEntries[2].shader);
  751.     }
  752.     faceColor.r = 0.3;
  753.     faceColor.g = 0.9;
  754.     faceColor.b = 0.9;
  755.     AttributeSet_AddDiffuseColor(boxData.faceAttributeSet[2], &faceColor);
  756.     
  757.     boxData.faceAttributeSet[3] = Q3AttributeSet_New();
  758.     if(gTextureEntries[3].shader != NULL)
  759.     {
  760.         AttributeSet_AddSurfaceShader(
  761.             boxData.faceAttributeSet[3],
  762.             (TQ3SurfaceShaderObject *)&gTextureEntries[3].shader);
  763.     }
  764.     faceColor.r = 0.5;
  765.     faceColor.g = 0.5;
  766.     faceColor.b = 0.5;
  767.     AttributeSet_AddTransparencyColor(boxData.faceAttributeSet[3], &faceColor);
  768.     faceColor.r = 0.4;
  769.     faceColor.g = 0.4;
  770.     faceColor.b = 0.4;
  771.     AttributeSet_AddDiffuseColor(boxData.faceAttributeSet[3], &faceColor);
  772.     
  773.     if(gTextureEntries[4].shader != NULL)
  774.     {
  775.         
  776.         boxData.faceAttributeSet[4] = Q3AttributeSet_New();
  777.         
  778.         AttributeSet_AddSurfaceShader(
  779.             boxData.faceAttributeSet[4],
  780.             (TQ3SurfaceShaderObject *)&gTextureEntries[4].shader);
  781.     }
  782.     
  783.     if(gTextureEntries[5].shader != NULL)
  784.     {
  785.         
  786.         boxData.faceAttributeSet[5] = Q3AttributeSet_New();
  787.         
  788.         AttributeSet_AddSurfaceShader(
  789.             boxData.faceAttributeSet[5],
  790.             (TQ3SurfaceShaderObject *)&gTextureEntries[5].shader);
  791.     }
  792.     
  793.     boxThang = Q3Box_New(&boxData);
  794.     
  795.     model = Q3OrderedDisplayGroup_New();
  796.     Q3Group_AddObject(model, boxThang);    
  797.     
  798.     {
  799.         register unsigned long i;
  800.         
  801.         for (i = 0; i < 6; i++) {
  802.             if(boxData.faceAttributeSet[i] != NULL)
  803.             {
  804.                 Q3Object_Dispose(boxData.faceAttributeSet[i]);
  805.             }
  806.         }
  807.     }
  808.  
  809.     Q3Object_Dispose(boxData.boxAttributeSet);
  810.     free(boxData.faceAttributeSet);
  811.     Q3Object_Dispose(boxThang);
  812.     
  813.     return (model);    
  814. }
  815.  
  816.  
  817.  
  818.  
  819.  
  820.  
  821.  
  822.  
  823. /*===========================================================================*\
  824.  *
  825.  *    Routine:    BuildNURBCurve()
  826.  *
  827.  *    Comments:    
  828.  *
  829. \*===========================================================================*/
  830.     
  831. static TQ3GroupObject BuildNURBCurve(
  832.     void)
  833. {
  834.     TQ3ColorRGB            curveColor;
  835.  
  836.     TQ3GroupObject        model;
  837.     TQ3NURBCurveData        curveData;
  838.     TQ3GeometryObject    curveThang;
  839.     static TQ3RationalPoint4D    points[7] = {
  840.                             { -1.0, -1.0,  0.0, 1.0 },
  841.                             { -1.5,  0.0,  0.0, 1.0 },
  842.                             { -1.0,  1.0,  0.0, 1.0 },
  843.                             {  0.0,  1.5,  0.0, 1.0 },
  844.                             {  1.0,  1.0,  0.0, 1.0 },
  845.                             {  1.5,  0.0,  0.0, 1.0 },
  846.                             {  1.0, -1.0,  0.0, 1.0 },
  847.                         };
  848.     static float        knots[11] = {
  849.                             0, 0, 0, 0, 0.25, 0.5, 0.75, 1, 1, 1, 1
  850.                         };
  851.  
  852.     
  853.     curveData.order                     = 4;
  854.     curveData.numPoints                    = 7;
  855.     curveData.controlPoints                 = points;
  856.     curveData.knots                     = knots;
  857.     curveData.curveAttributeSet         = Q3AttributeSet_New();
  858.     
  859.     curveColor.r = 0.8;
  860.     curveColor.g = 0.2;
  861.     curveColor.b = 0.6;
  862.     AttributeSet_AddDiffuseColor(curveData.curveAttributeSet, &curveColor);
  863.     
  864.     curveThang = Q3NURBCurve_New(&curveData);
  865.     
  866.     model = Q3OrderedDisplayGroup_New();
  867.     Q3Group_AddObject(model, curveThang);    
  868.     Q3Object_Dispose(curveData.curveAttributeSet);
  869.     Q3Object_Dispose(curveThang);
  870.     
  871.     {
  872.         unsigned long         i;
  873.         TQ3MarkerData        markerData;
  874.         TQ3GeometryObject    markerThang;
  875.         TQ3ColorRGB            markerColor;
  876.         TQ3Bitmap            *bitmapPtr = &markerData.bitmap;
  877.         unsigned char        imageData[] = { 0x20, 0x50, 0x88, 0x50, 0x20 };
  878.     
  879.         bitmapPtr->image     = imageData;
  880.         bitmapPtr->width     = 5;
  881.         bitmapPtr->height     = 5;
  882.         bitmapPtr->rowBytes = 1;
  883.         bitmapPtr->bitOrder    = kQ3EndianBig;
  884.  
  885.         Q3ColorRGB_Set(&markerColor, 0.0, 0.0, 0.0);
  886.         markerData.xOffset    = -2;
  887.         markerData.yOffset    = -2;
  888.         markerData.markerAttributeSet = Q3AttributeSet_New();
  889.         
  890.         AttributeSet_AddDiffuseColor(markerData.markerAttributeSet, 
  891.                                        &markerColor);    
  892.             
  893.         for (i = 0; i < curveData.numPoints; i++) {
  894.             Q3Point3D_Set(&markerData.location, 
  895.                           points[i].x / points[i].w,
  896.                           points[i].y / points[i].w,
  897.                           points[i].z / points[i].w);
  898.                 
  899.             markerThang = Q3Marker_New(&markerData);
  900.             Q3Group_AddObject(model, markerThang);
  901.             Q3Object_Dispose(markerThang);
  902.         }
  903.         
  904.         Q3Object_Dispose(markerData.markerAttributeSet);
  905.     }
  906.     
  907.     {
  908.         TQ3PolyLineData            polyLineData;
  909.         TQ3ColorRGB                polyLineColor;
  910.         TQ3GeometryObject        polyLine;
  911.         register unsigned long    i;
  912.         
  913.         polyLineData.numVertices = curveData.numPoints;
  914.         polyLineData.vertices = malloc(polyLineData.numVertices * sizeof(TQ3Vertex3D));
  915.         
  916.         for (i = 0; i < curveData.numPoints; i++) {
  917.             polyLineData.vertices[i].point.x = 
  918.                 curveData.controlPoints[i].x / curveData.controlPoints[i].w;
  919.             polyLineData.vertices[i].point.y = 
  920.                 curveData.controlPoints[i].y / curveData.controlPoints[i].w;
  921.             polyLineData.vertices[i].point.z = 
  922.                 curveData.controlPoints[i].z / curveData.controlPoints[i].w;
  923.             polyLineData.vertices[i].attributeSet = NULL;
  924.         }
  925.         
  926.         polyLineData.segmentAttributeSet = NULL;
  927.         polyLineData.polyLineAttributeSet = Q3AttributeSet_New();
  928.         
  929.         polyLine = Q3PolyLine_New(&polyLineData);
  930.         Q3ColorRGB_Set(&polyLineColor, 0.0, 0.0, 0.0);
  931.         AttributeSet_AddDiffuseColor(polyLineData.polyLineAttributeSet, 
  932.                                      &polyLineColor);    
  933.         
  934.         Q3Group_AddObject(model, polyLine);
  935.         
  936.         free(polyLineData.vertices);
  937.         
  938.         Q3Object_Dispose(polyLine);
  939.         Q3Object_Dispose(polyLineData.polyLineAttributeSet);
  940.     }
  941.  
  942.     return (model);    
  943. }
  944.  
  945.  
  946. static TQ3GroupObject BuildNURBPatch(
  947.     void)
  948. {
  949.     TQ3GroupObject                        model;
  950.     TQ3NURBPatchData                    patchData;
  951.     TQ3GeometryObject                    patchThang;
  952.     TQ3NURBPatchTrimLoopData            trimLoops[2];
  953.     TQ3NURBPatchTrimCurveData            trimCurveZero, trimCurveOne;
  954.         
  955.     static TQ3RationalPoint4D    vertices[12] = {
  956.                             { -2.0, -2.0, 0, 1.0 },
  957.                             { -1.0, -2.0, 1, 1.0 },
  958.                             {  1.0, -2.0, 0, 1.0 },
  959.                             {  2.0, -2.0, 0, 1.0 },
  960.  
  961.                             { -2.0, -1.0, 0, 1.0 },
  962.                             { -1.0, -1.0, 1, 1.0 },
  963.                             {  1.0, -1.0, -1, 1.0 },
  964.                             {  2.0, -1.0, -1, 1.0 },
  965.  
  966.                             { -2.0, -0.0, 0, 1.0 },
  967.                             { -1.0, -0.0, 0, 1.0 },
  968.                             {  1.0, -0.0, 0, 1.0 },
  969.                             {  2.0, -0.0, 0, 1.0 },
  970.                         };
  971.                         
  972.     static float        vKnots[6] = {
  973.                             0, 0, 0, 1, 1, 1
  974.                         };
  975.     static float        uKnots[8] = {
  976.                             0, 0, 0, 0, 1, 1, 1, 1, 
  977.                         };
  978.  
  979.     static TQ3RationalPoint3D    trimPointsZero[5] = {
  980.                             { 0.1, 0.1, 1.0 },
  981.                             { 0.9, 0.1, 1.0 },
  982.                             { 0.4, 0.4, 1.0 },
  983.                             { 0.1, 0.4, 1.0 },
  984.                             { 0.1, 0.1, 1.0 },
  985.                         };
  986.             
  987.     static float        trimKnotsZero[9] = {
  988.                             0, 0, 0, 0, 0.5, 1, 1, 1, 1    
  989.                         };
  990.                         
  991.     static TQ3RationalPoint3D    trimPointsOne[5] = {
  992.                             { 0.3, 0.6, 1.0 },
  993.                             { 0.9, 0.6, 1.0 },
  994.                             { 0.4, 0.9, 1.0 },
  995.                             { 0.2, 0.9, 1.0 },
  996.                             { 0.3, 0.6, 1.0 },
  997.                         };
  998.             
  999.     static float        trimKnotsOne[9] = {
  1000.                             0, 0, 0, 0, 0.5, 1, 1, 1, 1    
  1001.                         };
  1002.  
  1003.                     
  1004.     trimLoops[0].numTrimCurves     = 1;
  1005.     trimLoops[0].trimCurves        = &trimCurveZero;    
  1006.     
  1007.     trimCurveZero.order            = 4;
  1008.     trimCurveZero.numPoints        = 5;
  1009.     trimCurveZero.knots            = trimKnotsZero;
  1010.     trimCurveZero.controlPoints = trimPointsZero;
  1011.     
  1012.     trimLoops[1].numTrimCurves     = 1;
  1013.     trimLoops[1].trimCurves        = &trimCurveOne;    
  1014.     
  1015.     trimCurveOne.order            = 4;
  1016.     trimCurveOne.numPoints        = 5;
  1017.     trimCurveOne.knots            = trimKnotsOne;
  1018.     trimCurveOne.controlPoints     = trimPointsOne;
  1019.                             
  1020.     patchData.uOrder            = 4;
  1021.     patchData.vOrder            = 3;
  1022.     patchData.numColumns        = 4;
  1023.     patchData.numRows            = 3;
  1024.     patchData.uKnots            = uKnots;
  1025.     patchData.vKnots            = vKnots;
  1026.     patchData.controlPoints     = vertices;
  1027. #if 0
  1028.     patchData.numTrimLoops        = 2;
  1029.     patchData.trimLoops         = trimLoops;
  1030. #else
  1031.     patchData.numTrimLoops        = 0;
  1032.     patchData.trimLoops         = NULL;
  1033. #endif  /*  ESCHER_VER_15  */
  1034.  
  1035.     
  1036.     patchData.patchAttributeSet = Q3AttributeSet_New();
  1037.     {
  1038.         TQ3ColorRGB    patchColor;
  1039.         
  1040.         patchColor.r = 0.9;
  1041.         patchColor.g = 0.2;
  1042.         patchColor.b = 0.9;
  1043.         AttributeSet_AddDiffuseColor(patchData.patchAttributeSet, &patchColor);
  1044.     }
  1045.  
  1046.     
  1047.     patchThang = Q3NURBPatch_New(&patchData);
  1048.     
  1049.     model = Q3OrderedDisplayGroup_New();
  1050.     
  1051.     Q3Group_AddObject(model, patchThang);    
  1052.     Q3Object_Dispose(patchThang);
  1053.     Q3Object_Dispose(patchData.patchAttributeSet);
  1054.  
  1055.  
  1056.     {
  1057.         unsigned long         i;
  1058.         TQ3MarkerData        markerData;
  1059.         TQ3GeometryObject    markerThang;
  1060.         TQ3ColorRGB            markerColor;
  1061.         TQ3Bitmap            *bitmapPtr = &markerData.bitmap;
  1062.         unsigned char        imageData[] = { 0x20, 0x50, 0x88, 0x50, 0x20 };
  1063.     
  1064.         bitmapPtr->image     = imageData;
  1065.         bitmapPtr->width     = 5;
  1066.         bitmapPtr->height     = 5;
  1067.         bitmapPtr->rowBytes = 1;
  1068.         bitmapPtr->bitOrder    = kQ3EndianBig;
  1069.  
  1070.  
  1071.         Q3ColorRGB_Set(&markerColor, 0.1, 1.0, 0.6);
  1072.         markerData.xOffset    = -2;
  1073.         markerData.yOffset    = -2;
  1074.         markerData.markerAttributeSet = Q3AttributeSet_New();
  1075.         
  1076.         AttributeSet_AddDiffuseColor(markerData.markerAttributeSet, 
  1077.                                        &markerColor);    
  1078.             
  1079.         for (i = 0; i < patchData.numColumns * patchData.numRows; i++) {
  1080.             Q3Point3D_Set(&markerData.location, 
  1081.                           vertices[i].x / vertices[i].w,
  1082.                           vertices[i].y / vertices[i].w,
  1083.                           vertices[i].z / vertices[i].w);
  1084.                                           
  1085.             markerThang = Q3Marker_New(&markerData);
  1086.             Q3Group_AddObject(model, markerThang);
  1087.             Q3Object_Dispose(markerThang);
  1088.         }
  1089.         
  1090.         Q3Object_Dispose(markerData.markerAttributeSet);
  1091.     }
  1092.     
  1093.     return (model);    
  1094. }
  1095.  
  1096.  
  1097. /*===========================================================================*\
  1098.  *
  1099.  *    Routine:    BuildCursor_NewQuadFace()
  1100.  *
  1101.  *    Comments:    Builds a quad face.
  1102.  *
  1103. \*===========================================================================*/
  1104.  
  1105. static TQ3MeshFace BuildCursor_NewQuadFace (
  1106.     TQ3GeometryObject    mesh,
  1107.     TQ3MeshVertex        vertex[],
  1108.     int                    index0,
  1109.     int                    index1,
  1110.     int                    index2,
  1111.     int                    index3)
  1112. {
  1113.     TQ3MeshFace            result;
  1114.     TQ3MeshVertex        v[4];
  1115.     
  1116.     v[0] = vertex[index0];
  1117.     v[1] = vertex[index1];
  1118.     v[2] = vertex[index2];
  1119.     v[3] = vertex[index3];
  1120.     
  1121.     result = Q3Mesh_FaceNew(mesh, 4, v, NULL);
  1122.     
  1123.     return (result);
  1124. }
  1125.  
  1126.  
  1127.  
  1128. /*===========================================================================*\
  1129.  *
  1130.  *    Routine:    BuildCursor_NewQuads()
  1131.  *
  1132.  *    Comments:    Builds a quadralateral from the given points.
  1133.  *
  1134. \*===========================================================================*/
  1135.  
  1136. static TQ3Status BuildCursor_NewQuads (
  1137.     TQ3GeometryObject    mesh,
  1138.     unsigned long        faceMask,
  1139.     float x0, float y0, float z0,
  1140.     float x1, float y1, float z1,
  1141.     float x2, float y2, float z2,
  1142.     float x3, float y3, float z3,
  1143.     float x4, float y4, float z4,
  1144.     float x5, float y5, float z5,
  1145.     float x6, float y6, float z6,
  1146.     float x7, float y7, float z7)
  1147. {
  1148.     TQ3Vertex3D            point;
  1149.     TQ3MeshVertex        vertex[8];
  1150.     
  1151.     /*
  1152.      *    Make the vertices
  1153.      */
  1154.     
  1155.     point.attributeSet = NULL;
  1156.     Q3Point3D_Set(&point.point,x0,y0,z0);
  1157.     if ((vertex[0] = Q3Mesh_VertexNew(mesh,&point)) == NULL) return (kQ3Failure);
  1158.     Q3Point3D_Set(&point.point,x1,y1,z1);
  1159.     if ((vertex[1] = Q3Mesh_VertexNew(mesh,&point)) == NULL) return (kQ3Failure);
  1160.     Q3Point3D_Set(&point.point,x2,y2,z2);
  1161.     if ((vertex[2] = Q3Mesh_VertexNew(mesh,&point)) == NULL) return (kQ3Failure);
  1162.     Q3Point3D_Set(&point.point,x3,y3,z3);
  1163.     if ((vertex[3] = Q3Mesh_VertexNew(mesh,&point)) == NULL) return (kQ3Failure);
  1164.     Q3Point3D_Set(&point.point,x4,y4,z4);
  1165.     if ((vertex[4] = Q3Mesh_VertexNew(mesh,&point)) == NULL) return (kQ3Failure);
  1166.     Q3Point3D_Set(&point.point,x5,y5,z5);
  1167.     if ((vertex[5] = Q3Mesh_VertexNew(mesh,&point)) == NULL) return (kQ3Failure);
  1168.     Q3Point3D_Set(&point.point,x6,y6,z6);
  1169.     if ((vertex[6] = Q3Mesh_VertexNew(mesh,&point)) == NULL) return (kQ3Failure);
  1170.     Q3Point3D_Set(&point.point,x7,y7,z7);
  1171.     if ((vertex[7] = Q3Mesh_VertexNew(mesh,&point)) == NULL) return (kQ3Failure);
  1172.     
  1173.     
  1174.     /*
  1175.      *    Make the faces
  1176.      */
  1177.     
  1178.     if (faceMask & (1<<0)) if (BuildCursor_NewQuadFace(mesh,vertex,0,3,2,1) == NULL) return (kQ3Failure);
  1179.     if (faceMask & (1<<1)) if (BuildCursor_NewQuadFace(mesh,vertex,4,7,6,5) == NULL) return (kQ3Failure);
  1180.     if (faceMask & (1<<2)) if (BuildCursor_NewQuadFace(mesh,vertex,4,0,1,5) == NULL) return (kQ3Failure);
  1181.     if (faceMask & (1<<3)) if (BuildCursor_NewQuadFace(mesh,vertex,7,6,2,3) == NULL) return (kQ3Failure);
  1182.     if (faceMask & (1<<4)) if (BuildCursor_NewQuadFace(mesh,vertex,4,7,3,0) == NULL) return (kQ3Failure);
  1183.     if (faceMask & (1<<5)) if (BuildCursor_NewQuadFace(mesh,vertex,5,1,2,6) == NULL) return (kQ3Failure);
  1184.     
  1185.     
  1186.     return (kQ3Success);
  1187. }
  1188.  
  1189.  
  1190.  
  1191. /*===========================================================================*\
  1192.  *
  1193.  *    Routine:    BuildCursor()
  1194.  *
  1195.  *    Comments:    
  1196.  *
  1197. \*===========================================================================*/
  1198.     
  1199. static TQ3GroupObject BuildCursor(
  1200.     void)
  1201. {
  1202.     TQ3GeometryObject    mesh            = NULL;
  1203.     TQ3GroupObject        group            = NULL;
  1204.     
  1205.     /*
  1206.      *    Create the mesh
  1207.      */
  1208.     
  1209.     mesh = Q3Mesh_New ();
  1210.     if (mesh == NULL) goto bail;
  1211.     
  1212.     Q3Mesh_DelayUpdates (mesh);
  1213.     
  1214.     
  1215.     /*
  1216.      *    Tip
  1217.      */
  1218.     
  1219.     /*** ??? WOULD THESE BE BETTER DONE WITH MESH CORNERS? ***/
  1220.     
  1221.     if (BuildCursor_NewQuads (    mesh,
  1222.                             (0<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5),
  1223.                              0.00,  0.00,  0.00,
  1224.                              0.00,  0.00,  0.00,
  1225.                              0.00,  0.00,  0.00,
  1226.                              0.00,  0.00,  0.00,
  1227.                              0.50,  0.25,  0.05,
  1228.                              0.50, -0.25,  0.05,
  1229.                              0.50, -0.25, -0.05,
  1230.                              0.50,  0.25, -0.05) != kQ3Success)
  1231.         goto bail;
  1232.     
  1233.     
  1234.     /*
  1235.      *    Tail
  1236.      */
  1237.     
  1238.     if (BuildCursor_NewQuads (    mesh,
  1239.                             (0<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5),
  1240.                              0.50,  0.05,  0.05,
  1241.                              0.50, -0.05,  0.05,
  1242.                              0.50, -0.05, -0.05,
  1243.                              0.50,  0.05, -0.05,
  1244.                              1.00,  0.10,  0.10,
  1245.                              1.00, -0.10,  0.10,
  1246.                              1.00, -0.10, -0.10,
  1247.                              1.00,  0.10, -0.10) != kQ3Success)
  1248.         goto bail;
  1249.     
  1250.     Q3Mesh_ResumeUpdates (mesh);
  1251.     
  1252.     
  1253.     /*
  1254.      *    Build the group
  1255.      */
  1256.     
  1257.     group = Q3OrderedDisplayGroup_New ();
  1258.     if (group == NULL) goto bail;
  1259.     
  1260.     Q3Group_AddObject (group, mesh);
  1261.     Q3Object_Dispose (mesh);
  1262.     mesh = NULL;
  1263.     
  1264.     
  1265.     return (group);
  1266.     
  1267.     /*
  1268.      *    Error exit
  1269.      */
  1270.     
  1271.     bail:
  1272.     if (mesh    != NULL) Q3Object_Dispose (mesh);
  1273.     if (group    != NULL) Q3Object_Dispose (group);
  1274.     
  1275.     return (NULL);
  1276. }
  1277.  
  1278.  
  1279.  
  1280.  
  1281. /*===========================================================================*\
  1282.  *
  1283.  *    Routine:    BuildMesh()
  1284.  *
  1285.  *    Comments:    
  1286.  *
  1287. \*===========================================================================*/
  1288. /*
  1289.  
  1290.     Mesh (
  1291.         9 # nVertices
  1292.         { { -0.5,      0.5,    0.0 }, NULL },
  1293.         { { -0.5,    -0.5,    0.0 }, NULL },
  1294.         { {  0.0,    -0.5,     0.3 }, NULL },
  1295.         { {  0.5,     -0.5,     0.0 }, NULL },
  1296.         { {  0.5,      0.5,    0.0 }, NULL },
  1297.         { {  0.0,      0.5,    0.3 }, NULL },
  1298.         { { -0.4,      0.2,    0.0 }, NULL },
  1299.         { {  0.0,     0.0,    0.0 }, NULL },
  1300.         { { -0.4,     -0.2,    0.0 }, NULL },
  1301.         2 # nFaces
  1302.         1 # nContours
  1303.         4 0 1 2 5 # 0
  1304.         -3 6 7 8 # 2
  1305.         4 2 3 4 5 # 1
  1306.     )
  1307.  
  1308. */    
  1309.  
  1310. static TQ3GroupObject BuildMesh(
  1311.     void)
  1312. {
  1313.     TQ3ColorRGB            meshColor;
  1314.     TQ3GroupObject        model;
  1315.     static TQ3Vertex3D    vertices[9] = {
  1316.         { { -0.5,      0.5,    0.0  }, NULL },    // 1
  1317.         { { -0.5,    -0.5,    0.0  }, NULL },    // 2
  1318.         { {  0.0,    -0.5,     0.3  }, NULL },    // 3
  1319.         { {  0.5,     -0.5,     0.0  }, NULL },    // 4
  1320.         { {  0.5,      0.5,    0.0  }, NULL },    // 5
  1321.         { {  0.0,      0.5,    0.3  }, NULL },    // 6
  1322.         { { -0.4,      0.2,    0.0 }, NULL },    // 7
  1323.         { {  0.0,     0.0,    0.0  }, NULL },    // 8
  1324.         { { -0.4,     -0.2,    0.0 }, NULL },    // 9
  1325.                         };
  1326.     static TQ3Param2D    verticesUV[9] = {
  1327.         {0.0, 1.0}, {0.0, 0.0}, {0.5, 0.0}, {1.0, 0.0},
  1328.         {1.0, 1.0}, {0.5, 1.0}, {0.1, 0.8}, {0.5, 0.5},
  1329.         {0.1, 0.4}};
  1330.         
  1331.     TQ3MeshVertex        meshVertices[9];
  1332.     TQ3GeometryObject    mesh;
  1333.     TQ3MeshFace            meshFace;
  1334.     TQ3AttributeSet    faceAttributes;
  1335.     unsigned long        i;
  1336.     
  1337.     mesh = Q3Mesh_New();
  1338.  
  1339.     Q3Mesh_DelayUpdates( mesh);
  1340.     
  1341.     for (i = 0; i < 9; i++) {
  1342.         TQ3AttributeSet vertexASet;
  1343.         
  1344.         meshVertices[i] = Q3Mesh_VertexNew(mesh, &vertices[i]);
  1345.         vertexASet = Q3AttributeSet_New();
  1346.         AttributeSet_AddSurfaceUV(vertexASet, &verticesUV[i]);
  1347.  
  1348.         Q3Mesh_SetVertexAttributeSet( mesh, meshVertices[i],vertexASet);
  1349.         Q3Object_Dispose(vertexASet);
  1350.     }
  1351.     
  1352.     faceAttributes = Q3AttributeSet_New();
  1353.     meshColor.r = 0.3;
  1354.     meshColor.g = 0.9;
  1355.     meshColor.b = 0.5;
  1356.     AttributeSet_AddDiffuseColor(faceAttributes, &meshColor);
  1357.  
  1358.     meshFace = Q3Mesh_FaceNew(mesh, 6, meshVertices, faceAttributes);
  1359.  
  1360.     Q3Mesh_FaceToContour( mesh,meshFace,Q3Mesh_FaceNew(mesh, 3, &meshVertices[6], NULL));
  1361.     
  1362.     Q3Mesh_ResumeUpdates( mesh);
  1363.     
  1364.     model = Q3OrderedDisplayGroup_New();
  1365.     
  1366.     Q3Group_AddObject(model, mesh);    
  1367.  
  1368.     Q3Object_Dispose(faceAttributes);
  1369.     Q3Object_Dispose(mesh);
  1370.     
  1371.     return (model);    
  1372. }
  1373.  
  1374.  
  1375.